<!DOCTYPE html>
<html>

<head>

<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
<title>README</title>


<style type="text/css">
body {
  font-family: Helvetica, arial, sans-serif;
  font-size: 14px;
  line-height: 1.6;
  padding-top: 10px;
  padding-bottom: 10px;
  background-color: white;
  padding: 30px; }

body > *:first-child {
  margin-top: 0 !important; }
body > *:last-child {
  margin-bottom: 0 !important; }

a {
  color: #4183C4; }
a.absent {
  color: #cc0000; }
a.anchor {
  display: block;
  padding-left: 30px;
  margin-left: -30px;
  cursor: pointer;
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0; }

h1, h2, h3, h4, h5, h6 {
  margin: 20px 0 10px;
  padding: 0;
  font-weight: bold;
  -webkit-font-smoothing: antialiased;
  cursor: text;
  position: relative; }

h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor, h5:hover a.anchor, h6:hover a.anchor {
  background: url() no-repeat 10px center;
  text-decoration: none; }

h1 tt, h1 code {
  font-size: inherit; }

h2 tt, h2 code {
  font-size: inherit; }

h3 tt, h3 code {
  font-size: inherit; }

h4 tt, h4 code {
  font-size: inherit; }

h5 tt, h5 code {
  font-size: inherit; }

h6 tt, h6 code {
  font-size: inherit; }

h1 {
  font-size: 28px;
  color: black; }

h2 {
  font-size: 24px;
  border-bottom: 1px solid #cccccc;
  color: black; }

h3 {
  font-size: 18px; }

h4 {
  font-size: 16px; }

h5 {
  font-size: 14px; }

h6 {
  color: #777777;
  font-size: 14px; }

p, blockquote, ul, ol, dl, li, table, pre {
  margin: 15px 0; }

hr {
  background: transparent url() repeat-x 0 0;
  border: 0 none;
  color: #cccccc;
  height: 4px;
  padding: 0;
}

body > h2:first-child {
  margin-top: 0;
  padding-top: 0; }
body > h1:first-child {
  margin-top: 0;
  padding-top: 0; }
  body > h1:first-child + h2 {
    margin-top: 0;
    padding-top: 0; }
body > h3:first-child, body > h4:first-child, body > h5:first-child, body > h6:first-child {
  margin-top: 0;
  padding-top: 0; }

a:first-child h1, a:first-child h2, a:first-child h3, a:first-child h4, a:first-child h5, a:first-child h6 {
  margin-top: 0;
  padding-top: 0; }

h1 p, h2 p, h3 p, h4 p, h5 p, h6 p {
  margin-top: 0; }

li p.first {
  display: inline-block; }
li {
  margin: 0; }
ul, ol {
  padding-left: 30px; }

ul :first-child, ol :first-child {
  margin-top: 0; }

dl {
  padding: 0; }
  dl dt {
    font-size: 14px;
    font-weight: bold;
    font-style: italic;
    padding: 0;
    margin: 15px 0 5px; }
    dl dt:first-child {
      padding: 0; }
    dl dt > :first-child {
      margin-top: 0; }
    dl dt > :last-child {
      margin-bottom: 0; }
  dl dd {
    margin: 0 0 15px;
    padding: 0 15px; }
    dl dd > :first-child {
      margin-top: 0; }
    dl dd > :last-child {
      margin-bottom: 0; }

blockquote {
  border-left: 4px solid #dddddd;
  padding: 0 15px;
  color: #777777; }
  blockquote > :first-child {
    margin-top: 0; }
  blockquote > :last-child {
    margin-bottom: 0; }

table {
  padding: 0;border-collapse: collapse; }
  table tr {
    border-top: 1px solid #cccccc;
    background-color: white;
    margin: 0;
    padding: 0; }
    table tr:nth-child(2n) {
      background-color: #f8f8f8; }
    table tr th {
      font-weight: bold;
      border: 1px solid #cccccc;
      margin: 0;
      padding: 6px 13px; }
    table tr td {
      border: 1px solid #cccccc;
      margin: 0;
      padding: 6px 13px; }
    table tr th :first-child, table tr td :first-child {
      margin-top: 0; }
    table tr th :last-child, table tr td :last-child {
      margin-bottom: 0; }

img {
  max-width: 100%; }

span.frame {
  display: block;
  overflow: hidden; }
  span.frame > span {
    border: 1px solid #dddddd;
    display: block;
    float: left;
    overflow: hidden;
    margin: 13px 0 0;
    padding: 7px;
    width: auto; }
  span.frame span img {
    display: block;
    float: left; }
  span.frame span span {
    clear: both;
    color: #333333;
    display: block;
    padding: 5px 0 0; }
span.align-center {
  display: block;
  overflow: hidden;
  clear: both; }
  span.align-center > span {
    display: block;
    overflow: hidden;
    margin: 13px auto 0;
    text-align: center; }
  span.align-center span img {
    margin: 0 auto;
    text-align: center; }
span.align-right {
  display: block;
  overflow: hidden;
  clear: both; }
  span.align-right > span {
    display: block;
    overflow: hidden;
    margin: 13px 0 0;
    text-align: right; }
  span.align-right span img {
    margin: 0;
    text-align: right; }
span.float-left {
  display: block;
  margin-right: 13px;
  overflow: hidden;
  float: left; }
  span.float-left span {
    margin: 13px 0 0; }
span.float-right {
  display: block;
  margin-left: 13px;
  overflow: hidden;
  float: right; }
  span.float-right > span {
    display: block;
    overflow: hidden;
    margin: 13px auto 0;
    text-align: right; }

code, tt {
  margin: 0 2px;
  padding: 0 5px;
  white-space: nowrap;
  border: 1px solid #eaeaea;
  background-color: #f8f8f8;
  border-radius: 3px; }

pre code {
  margin: 0;
  padding: 0;
  white-space: pre;
  border: none;
  background: transparent; }

.highlight pre {
  background-color: #f8f8f8;
  border: 1px solid #cccccc;
  font-size: 13px;
  line-height: 19px;
  overflow: auto;
  padding: 6px 10px;
  border-radius: 3px; }

pre {
  background-color: #f8f8f8;
  border: 1px solid #cccccc;
  font-size: 13px;
  line-height: 19px;
  overflow: auto;
  padding: 6px 10px;
  border-radius: 3px; }
  pre code, pre tt {
    background-color: transparent;
    border: none; }

sup {
    font-size: 0.83em;
    vertical-align: super;
    line-height: 0;
}

kbd {
  display: inline-block;
  padding: 3px 5px;
  font-size: 11px;
  line-height: 10px;
  color: #555;
  vertical-align: middle;
  background-color: #fcfcfc;
  border: solid 1px #ccc;
  border-bottom-color: #bbb;
  border-radius: 3px;
  box-shadow: inset 0 -1px 0 #bbb
}

* {
	-webkit-print-color-adjust: exact;
}
@media screen and (min-width: 914px) {
    body {
        width: 854px;
        margin:0 auto;
    }
}
@media print {
	table, pre {
		page-break-inside: avoid;
	}
	pre {
		word-wrap: break-word;
	}
}
</style>


</head>

<body>

<h1 id="toc_0">OBMessenger Framework</h1>

<h5 id="toc_1">Version:1.2.0607 DocSet: 2017-06-09</h5>

<h2 id="toc_2"></h2>

<h1 id="toc_3">Install</h1>

<ol>
<li>Open <strong>Terminal</strong></li>
<li>Goto to your project folder location</li>
<li>Run <strong><code>curl -fsSL https://gitee.com/JasonGN/OB/raw/master/CarthageFW/install | sh</code></strong></li>
<li>On your application targets’ <strong>“General”</strong> settings tab, in the <strong>“Linked Frameworks and Libraries”</strong> section, drag and drop each framework you want to use from the <code>Carthage/Build</code> folder on disk.</li>
<li><p>On your application targets’ <strong>“Build Phases”</strong> settings tab, click the <strong>“+”</strong> icon and choose <strong>“New Run Script Phase”</strong>. </p>

<p>Create a Run Script in which you specify your shell (eg. <code>/bin/sh</code>), add the following contents to the script area below the shell:</p>

<div><pre><code class="language-none">/usr/local/bin/carthage copy-frameworks</code></pre></div>

<p>and add the paths to the frameworks you want to use under “Input Files”: </p>

<div><pre><code class="language-none">$(SRCROOT)/Carthage/Build/iOS/AFNetworking.framework
$(SRCROOT)/Carthage/Build/iOS/CocoaAsyncSocket.framework
$(SRCROOT)/Carthage/Build/iOS/OBMessenger.framework
$(SRCROOT)/Carthage/Build/iOS/OBUIExtension.framework</code></pre></div></li>
<li><p>Choice to use crash reporter, create a Run Script same as step 5, add the following contents to the script area below the shell:</p>

<div><pre><code class="language-none">./Carthage/Build/iOS/Crashlytics.framework/run d623929e3313eb531956b20c918cde88371cd34f 463a0d96cc7934efb6a38cf97edfaa970b4837692399250f99b336988e414c80</code></pre></div></li>
</ol>

<h2 id="toc_4"></h2>

<h1 id="toc_5">Initial</h1>

<ol>
<li><p>Import frameworks </p>

<ul>
<li>Recommend create Precompile Prefix Header and add the following contents.</li>
<li>Or in AppDelegate, add the following contents.</li>
</ul>

<div><pre><code class="language-none">#import &lt;OBMessenger/OBMessenger.h&gt;
#import &lt;OBUIExtension/OBUIExtension.h&gt;</code></pre></div></li>
<li><p>Init singleton manager <strong><code>[OBManager sharedOBManager];</code></strong></p>

<p>This will auto init modules and do </p>

<ul>
<li>Monitor network change;</li>
<li>Discover local OBox in LAN;</li>
<li>Cache OBox data to database;</li>
<li>Ready to log in server</li>
</ul></li>
</ol>

<h2 id="toc_6"></h2>

<h1 id="toc_7">OboxEntity</h1>

<ol>
<li>Object property

<ul>
<li>NSString *<strong>serial</strong> : obox serial, key for get object in database </li>
<li>NSString *name : obox name</li>
</ul></li>
<li>Get object(s)

<ul>
<li><em><code>+(nullable NSSet *)ctlGetAllUsingPredicate:(nullable NSArray&lt;NSPredicate *&gt;*)predicates;</code></em> return set of objects that is filtered by array of NSPredicate if have, or return nil if get nothing. More detail in OBEntityControl category of OboxEntity</li>
<li><em><code>[[OBManager model] getEntityForPrimaryKeyValue:&lt;#(target serial string)#&gt; ofType:OBM_Obox];</code></em> return specific serial oboxEntity object if database have.</li>
</ul></li>
<li>Discover OBox in Lan

<ul>
<li>By default, OBox is automatically discovered when WiFi is enabled</li>
<li>By manual, discover OBox using <em><code>+ctlDiscoverLocal</code></em></li>
</ul></li>
<li><p>Search nodes</p>

<p><em><code>-(void)ctlSearchNodeStart:(BOOL)startOrStop forTimeout:(NSUInteger)timeout handler:(nullable CtlResultBlock)inHandler;</code></em></p>

<ul>
<li>startOrStop set <code>YES</code> to activate searching or <code>NO</code> to cancle</li>
<li>timeout searching timeout priod</li>
<li>inHandler callback block with DeviceEntity object found, do some UI refreash if need.</li>
<li>More detail in OBEntityControl category of OboxEntity </li>
</ul></li>
<li><p>Release all nodes</p>

<p><em><code>-(void)ctlReleaseNodes:(nullable CtlResultBlock)inHandler;</code></em></p></li>
<li><p>Reset</p>

<p><em><code>-(void)ctlReset;</code></em></p></li>
</ol>

<h1 id="toc_8">DeviceEntity</h1>

<ol>
<li>Object property

<ul>
<li>NSString *<strong>serial</strong> : node serial, key for get object in database </li>
<li>NSString *name : node name</li>
<li>NSString *obox_serial : serial of obox that contains itself</li>
<li>NSString *addr : hexstring address of node in the obox</li>
<li>DEVICETYPE type : node type, see <code>DEVICETYPE</code> enum</li>
<li>int child_type : node sub-type</li>
<li>NSString *state : hexstring current state of node (8 byte)</li>
</ul></li>
<li>Get object(s)

<ul>
<li><em><code>+(nullable NSSet *)ctlGetAllUsingPredicate:(nullable NSArray&lt;NSPredicate *&gt;*)predicates;</code></em> return set of objects that is filtered by array of NSPredicate if have, or return nil if get nothing. More detail in OBEntityControl category of DeviceEntity</li>
<li><em><code>[[OBManager model] getEntityForPrimaryKeyValue:&lt;#(target serial string)#&gt; ofType:OBM_Device];</code></em> return specific serial deviceEntity object if database have.</li>
</ul></li>
<li><p>Rename</p>

<p><em><code>-(void)ctlRename:(nonnull NSString *)newName handler:(nullable CtlResultBlock)inHandler;</code></em></p>

<ul>
<li>name string must be utf8 and formatted length max 16</li>
</ul></li>
<li><p>Release</p>

<p><em><code>-(void)ctlDelete:(nullable CtlResultBlock)inHandler;</code></em></p></li>
<li><p>Request state</p>

<p><em><code>-(void)ctlGetState:(nullable CtlResultBlock)inHandler;</code></em></p>

<ul>
<li>Refresh current node state, the inHandler callback block contains new state string</li>
</ul></li>
<li><p>Set state</p>

<p><em><code>-(void)ctlSetState:(nonnull NSString *)hexState handler:(nullable CtlResultBlock)inHandler;</code></em></p>

<ul>
<li>Set (Change) node state with 8 byte hexstring</li>
<li>Eg. <code>1122003344550100</code> means change LED to brightness 17/255 and cold temp 34/255 etc.</li>
</ul></li>
</ol>

<h1 id="toc_9">GroupEntity</h1>

<ol>
<li>Object property

<ul>
<li>int <strong>index</strong> : group index, @(index) key for get object in database </li>
<li>NSString *name : group name</li>
<li>NSString *obox_serial : serial of obox that contains itself, nil if group is in server store only</li>
<li>NSString *addr : hexstring address of group in the obox, nil if group is in server store only</li>
<li>DEVICETYPE type : group type, see <code>DEVICETYPE</code> enum</li>
<li>int child_type : group sub-type</li>
<li>NSString *state : hexstring current state of group (8 byte)</li>
<li>NSSet &lt;DeviceEntity*&gt; *members : group members, set of deviceEntity objects in the group</li>
<li>NSSet &lt;NSString*&gt; *memberSerials : group members&#39; serials, set of serial of member in the group</li>
</ul></li>
<li>Get object(s)

<ul>
<li><em><code>+(nullable NSSet *)ctlGetAllUsingPredicate:(nullable NSArray&lt;NSPredicate *&gt;*)predicates;</code></em> return set of objects that is filtered by array of NSPredicate if have, or return nil if get nothing. More detail in OBEntityControl category of GroupEntity</li>
<li><em><code>[[OBManager model] getEntityForPrimaryKeyValue:&lt;#(target index NSNumber)#&gt; ofType:OBM_Group];</code></em> return specific index groupEntity object if database have.</li>
</ul></li>
<li><p>Create</p>

<p><em><code>+(void)ctlCreateAsName:(nonnull NSString *)groupName serverOrLocalBox:(nullable OboxEntity *)targetBox  ofType:(DEVICETYPE)type handler:(nullable CtlResultBlock)inHandler;</code></em></p>

<ul>
<li>groupName string must be utf8 and formatted length max 16</li>
<li>targetBox assign create group in which obox or set nil to store in server</li>
<li>type assign group device type</li>
<li>inHandler callback block with object created, do some UI refreash if need.</li>
</ul></li>
<li><p>Rename</p>

<p><em><code>-(void)ctlRename:(nonnull NSString *)newName handler:(nullable CtlResultBlock)inHandler;</code></em></p></li>
<li><p>Delete</p>

<p><em><code>-(void)ctlDelete:(nullable CtlResultBlock)inHandler;</code></em></p></li>
<li><p>Add member(s)</p>

<p><em><code>-(void)ctlAddMemberDevices:(nonnull NSSet&lt;DeviceEntity*&gt; *)devices handler:(nullable CtlResultBlock)inHandler;</code></em></p>

<ul>
<li>devices set of deviceEntities that want to add to the group</li>
<li>Warning: A node can only be a member of a group</li>
</ul></li>
<li><p>Remove member(s)</p>

<p><em><code>-(void)ctlRemoveMemberDevices:(nonnull NSSet&lt;DeviceEntity*&gt; *)devices handler:(nullable CtlResultBlock)inHandler;</code></em></p>

<ul>
<li>devices set of deviceEntities that want to remove out of the group</li>
</ul></li>
<li><p>Set state</p>

<p><em><code>-(void)ctlSetState:(nonnull NSString *)hexState handler:(nullable CtlResultBlock)inHandler;</code></em></p>

<ul>
<li>same as set node state above</li>
</ul></li>
</ol>

<h1 id="toc_10">Get object entity in database</h1>

<ul>
<li>Touch database <em><code>[OBManager model];</code></em></li>
<li><p>Get set of objects <em><code>[[OBManager model] getEntityUnitForType:&lt;#(OBMType)#&gt;];</code></em> by passing OBMType enum as parameter:</p>

<ul>
<li><code>OBM_Obox</code> to get OboxEntity</li>
<li><code>OBM_Device</code> to get DeviceEntity</li>
<li><code>OBM_Group</code> to get GroupEntity</li>
<li><code>OBM_Scene</code> to get SceneEntity</li>
<li><code>OBM_All</code> to get all object entities in database</li>
</ul>

<p>Return NSSet object contains specific type of entity or nil for nothing. Eg. <code>[[OBManager model] getEntityUnitForType:OBM_Device];</code> will return NSSet object contains all DeviceEntities in database or return nil if no device found.</p></li>
<li><p>Get specific entity <em><code>[[OBManager model] getEntityForPrimaryKeyValue:&lt;#(key of entity)#&gt; ofType:&lt;#(OBMType)#&gt;];</code></em> by passing the key of target entity and the type:</p>

<ul>
<li>Reference OBMType above</li>
<li>Reference Entity detail above of <code>key of entity</code></li>
</ul>

<p>Return specific entity object if have. Eg. <code>[[OBManager model] getEntityForPrimaryKeyValue:@&quot;1234000000&quot; ofType:OBM_Obox];</code> will return OboxEntity object that its serial is @&quot;1234000000&quot; if OBox3412 has been found.</p></li>
</ul>

<h2 id="toc_11"></h2>

<h1 id="toc_12">More detail</h1>

<ul>
<li><a href="https://jasongn.github.io/OB/">DocSet</a></li>
<li><a href="mailto://guonan_hong@on-bright.com">Mail to author</a></li>
</ul>




</body>

</html>
